package com.wiscamp.ninechapters.problems.application.services;

import com.wiscamp.ninechapters.problems.application.assemblers.PaperPartAssembler;
import com.wiscamp.ninechapters.problems.application.dto.commands.exams.CreatePaperPartCommand;
import com.wiscamp.ninechapters.problems.application.dto.commands.exams.CreatePaperSectionCommand;
import com.wiscamp.ninechapters.problems.application.dto.commands.exams.UpdatePaperPartCommand;
import com.wiscamp.ninechapters.problems.application.dto.commands.exams.UpdatePaperSectionCommand;
import com.wiscamp.ninechapters.problems.application.dto.vo.exams.PaperPartVO;
import com.wiscamp.ninechapters.problems.application.dto.vo.exams.PaperSectionVO;
import com.wiscamp.ninechapters.problems.domain.repositories.PaperPartRepository;
import com.wiscamp.ninechapters.problems.domain.services.PaperPartService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class PaperPartAppService extends BaseAppService {

    private final PaperPartRepository paperPartRepository;

    private final PaperPartService paperPartService;

    public PaperPartAppService(PaperPartRepository paperPartRepository, PaperPartService paperPartService) {
        this.paperPartRepository = paperPartRepository;
        this.paperPartService = paperPartService;
    }


    //region paper part

    @HandleServiceException
    public PaperPartVO getPaperPart(@Min(0) long partId) {
        return AppServiceUtils.getById(partId, paperPartRepository::getPaperPart,
                PaperPartAssembler.Instance::toPaperPartVO);
    }

    @HandleServiceException
    public Collection<PaperPartVO> getPaperPartsByExam(@Min(0) long examId) {
        return AppServiceUtils.getListById(examId, paperPartRepository::getPaperPartsByExam,
                PaperPartAssembler.Instance::toPaperPartVO);
    }

    @HandleServiceException
    public PaperPartVO createPaperPart(@NotNull CreatePaperPartCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), paperPartService::createPaperPart,
                PaperPartAssembler.Instance::toPaperPartVO, PaperPartAssembler.Instance::fromCreateCommand);

    }

    @HandleServiceException
    public PaperPartVO updatePaperPart(@NotNull UpdatePaperPartCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), paperPartService::updatePaperPart,
                PaperPartAssembler.Instance::toPaperPartVO, PaperPartAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deletePaperPart(DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), paperPartService::deletePaperPart);
    }

    //endregion

    //region paper section
    @HandleServiceException
    public PaperSectionVO getPaperSection(@Min(0) long sectionId) {
        return AppServiceUtils.getById(sectionId, paperPartRepository::getPaperSection,
                PaperPartAssembler.Instance::toPaperSectionVO);
    }

    @HandleServiceException
    public Collection<PaperSectionVO> getPaperSectionsByPart(@Min(0) long partId) {
        return AppServiceUtils.getListById(partId, paperPartRepository::getPaperSectionsByPart,
                PaperPartAssembler.Instance::toPaperSectionVO);
    }

    @HandleServiceException
    public PaperSectionVO createPaperSection(@NotNull CreatePaperSectionCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), paperPartService::createPaperSection,
                PaperPartAssembler.Instance::toPaperSectionVO, PaperPartAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public PaperSectionVO updatePaperSection(@NotNull UpdatePaperSectionCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), paperPartService::updatePaperSection,
                PaperPartAssembler.Instance::toPaperSectionVO, PaperPartAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deletePaperSection(@NotNull DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), paperPartService::deletePaperSection);
    }
    //endregion


}
